/**
 * Copyright (c) 2015-2016, Michael Yang 杨福海 (fuhai999@gmail.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jpress.front.controller;

import com.jfinal.core.Controller;
import io.jpress.Consts;
import io.jpress.core.cache.ActionCache;
import io.jpress.model.Content;
import io.jpress.model.Taxonomy;
import io.jpress.model.query.ContentQuery;
import io.jpress.model.query.OptionQuery;
import io.jpress.model.query.TaxonomyQuery;
import io.jpress.router.RouterMapping;
import io.jpress.utils.DateUtils;
import io.jpress.utils.StringUtils;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RouterMapping(url = "/sitemap")
public class SitemapController extends Controller {
    private static final String contentType = "text/xml; charset=" + Consts.CHARTSET_UTF8;

    static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:ss:mm'Z'");

    @ActionCache
    public void index() {
        StringBuilder xmlBuilder = new StringBuilder();
        buildSitemapHeader(xmlBuilder);
        String domain = OptionQuery.me().findValue("web_domain");
        if (StringUtils.isBlank(domain))
            domain = "";

        buildSitemap(xmlBuilder, domain + "/sitemap/site", format.format(new Date()));
        List<Taxonomy> taxonomys = TaxonomyQuery.me().findAll();
        if (taxonomys != null && !taxonomys.isEmpty()) {
            for (Taxonomy t : taxonomys) {
                buildSitemap(xmlBuilder, domain + "/sitemap/taxonomy/" + t.getId(), format.format(new Date()));
            }
        }
        buildSitemapFooter(xmlBuilder);
        renderText(xmlBuilder.toString(), contentType);
    }

    @ActionCache
    public void site() {
        StringBuilder xmlBuilder = new StringBuilder();
        buildUrlsetHeader(xmlBuilder);
        buildUrl(xmlBuilder, OptionQuery.me().findValue("web_domain"), format.format(new Date()), "always", "1.0");
        buildUrlsetFooter(xmlBuilder);
        renderText(xmlBuilder.toString(), contentType);
    }

    @ActionCache
    public void taxonomy() {
        String idString = getPara();
        if (StringUtils.isBlank(idString)) {
            renderText("", contentType);
        }

        BigInteger id = new BigInteger(idString);
        StringBuilder xmlBuilder = new StringBuilder();
        buildUrlsetHeader(xmlBuilder);
        String domain = OptionQuery.me().findValue("web_domain");
        List<Content> contents = ContentQuery.me().findListInNormal(1, 500, id);
        if (contents != null && !contents.isEmpty()) {
            for (Content c : contents) {
                if (c.getModified() == null)
                    continue;

                String changefreq = "daily";
                String priority = "1.0";
                int dayDiff = DateUtils.getDayDiff(new Date(), c.getModified());
                if (dayDiff > 30) {
                    changefreq = "monthly";
                    priority = "0.3";
                } else if (dayDiff > 7) {
                    changefreq = "weekly";
                    priority = "0.9";
                }

                buildUrl(xmlBuilder, domain + c.getUrl(), format.format(c.getModified()), changefreq, priority);
            }
        }
        buildUrlsetFooter(xmlBuilder);
        renderText(xmlBuilder.toString(), contentType);
    }

    private void buildSitemapHeader(StringBuilder xmlBuilder) {
        buildHeader(xmlBuilder);
        xmlBuilder.append("<sitemapindex ");
        xmlBuilder.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
        xmlBuilder.append(" xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\" ");
        xmlBuilder.append(" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" ");
        xmlBuilder.append(" > ");
    }

    private void buildSitemapFooter(StringBuilder xmlBuilder) {
        xmlBuilder.append("</sitemapindex>");
        buildFooter(xmlBuilder);
    }

    private void buildUrlsetHeader(StringBuilder xmlBuilder) {
        buildHeader(xmlBuilder);
        xmlBuilder.append("<urlset");
        xmlBuilder.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
        xmlBuilder.append(" xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\" ");
        xmlBuilder.append(" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" ");
        xmlBuilder.append(" > ");
    }

    private void buildUrlsetFooter(StringBuilder xmlBuilder) {
        xmlBuilder.append("</urlset>");
        buildFooter(xmlBuilder);
    }

    private void buildHeader(StringBuilder xmlBuilder) {
        xmlBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    }

    private void buildFooter(StringBuilder xmlBuilder) {
        xmlBuilder.append("<!-- This sitemap was generated by JPress --> ");
    }

    private void buildSitemap(StringBuilder xmlBuilder, String loc, String lastmod) {
        xmlBuilder.append("<sitemap>");
        xmlBuilder.append("<loc>" + loc + "</loc>");
        xmlBuilder.append("<lastmod>" + lastmod + "</lastmod>");
        xmlBuilder.append("</sitemap>");
    }

    private void buildUrl(StringBuilder xmlBuilder, String loc, String lastmod, String changefreq, String priority) {
        xmlBuilder.append("<url>");
        xmlBuilder.append("<loc>" + loc + "</loc>");
        xmlBuilder.append("<lastmod>" + lastmod + "</lastmod>");
        xmlBuilder.append("<changefreq>" + changefreq + "</changefreq>");
        xmlBuilder.append("<priority>" + priority + "</priority>");
        xmlBuilder.append("</url>");
    }

}
